package boot.spring.controller;


import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import boot.spring.config.CustomMinioClient;
import cn.hutool.core.io.FileUtil;
import io.minio.*;
import io.minio.messages.Part;
import org.apache.logging.log4j.core.util.FileUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import boot.spring.domain.AjaxResult;
import boot.spring.domain.Fileinfo;
import boot.spring.util.MinioUtil;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@Api(tags = "文件操作接口")
@Controller
public class FileController {
	
	@Autowired
	MinioUtil minioUtil;

	@Autowired
	private CustomMinioClient minioClient;


	@ApiOperation("上传一个文件")
	@RequestMapping(value = "/uploadfile", method = RequestMethod.POST)
	@ResponseBody
	public AjaxResult fileupload(@RequestParam MultipartFile uploadfile, @RequestParam String bucket, 
			@RequestParam(required=false) String objectName) throws Exception {
		minioUtil.createBucket(bucket);
		if (objectName != null) {
			minioUtil.uploadFile(uploadfile.getInputStream(), bucket, objectName+"/"+uploadfile.getOriginalFilename());
		} else {
			minioUtil.uploadFile(uploadfile.getInputStream(), bucket, uploadfile.getOriginalFilename());
		}
		return AjaxResult.success();
	}
	
	@ApiOperation("列出所有的桶")
	@RequestMapping(value = "/listBuckets", method = RequestMethod.GET)
	@ResponseBody
	public AjaxResult listBuckets() throws Exception {
		return AjaxResult.success(minioUtil.listBuckets());
	}
	
	@ApiOperation("递归列出一个桶中的所有文件和目录")
	@RequestMapping(value = "/listFiles", method = RequestMethod.GET)
	@ResponseBody
	public AjaxResult listFiles(@RequestParam String bucket) throws Exception {
		return AjaxResult.success("200", minioUtil.listFiles(bucket));
	}
	
	@ApiOperation("下载一个文件")
	@RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
	@ResponseBody
	public void downloadFile(@RequestParam String bucket, @RequestParam String objectName,
			HttpServletResponse response) throws Exception {
		InputStream stream = minioUtil.download(bucket, objectName);
		ServletOutputStream output = response.getOutputStream();
		response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(objectName.substring(objectName.lastIndexOf("/") + 1), "UTF-8"));
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("UTF-8");
		IOUtils.copy(stream, output);
	}
	
	
	@ApiOperation("删除一个文件")
	@RequestMapping(value = "/deleteFile", method = RequestMethod.GET)
	@ResponseBody
	public AjaxResult deleteFile(@RequestParam String bucket, @RequestParam String objectName) throws Exception {
		minioUtil.deleteObject(bucket, objectName);
		return AjaxResult.success();
	}

	@RequestMapping(value = "/mergeMultipartUpload", method = RequestMethod.GET)
	@ResponseBody
	public AjaxResult mergeMultipartUpload(@RequestParam String uploadId, @RequestParam String bucket, @RequestParam String obj) throws Exception {

		final ListPartsResponse listPartsResponse = minioClient.listMultipart(bucket, null, obj, 1000, 0, uploadId, null, null);

		final List<Part> parts = listPartsResponse.result().partList();

		final Part[] newParts = new Part[parts.size()];

		for (int i = 0; i < parts.size(); i++) {
			final Part part = parts.get(i);
			newParts[i] = part;
			System.out.println(part.etag() + "--" +part.partNumber());
		}

		final ObjectWriteResponse objectWriteResponse = minioClient.mergeMultipartUpload(bucket, null, obj, uploadId, newParts, null, null);
		return AjaxResult.success(objectWriteResponse.object());
	}

	@ApiOperation("删除一个桶")
	@RequestMapping(value = "/createUploadId", method = RequestMethod.GET)
	@ResponseBody
	public AjaxResult createUploadId(@RequestParam String bucket, @RequestParam String obj) throws Exception {
		minioUtil.createBucket(bucket);
		final String uploadId = minioClient.initMultiPartUpload(bucket, null, obj, null, null);

		final String file1 = "/Volumes/m2hk/mp3_00";
		final BufferedInputStream fileIO1 = FileUtil.getInputStream(file1);
		final long file1Size = FileUtil.size(new File(file1));
		minioClient.uploadPartFile(bucket, null, obj, fileIO1, (int) file1Size, uploadId, 1, null, null);

		final String file2 = "/Volumes/m2hk/mp3_01";
		final BufferedInputStream fileIO2 = FileUtil.getInputStream(file2);
		final long file2Size = FileUtil.size(new File(file2));
		minioClient.uploadPartFile(bucket, null, obj, fileIO2, (int) file2Size, uploadId, 2, null, null);

//		final String file3 = "/Volumes/m2hk/mp3_02";
//		final BufferedInputStream fileIO3 = FileUtil.getInputStream(file3);
//		final long file3Size = FileUtil.size(new File(file3));
//		minioClient.uploadPartFile(bucket, null, obj, fileIO3, (int) file3Size, uploadId, 3, null, null);

		final ListPartsResponse listPartsResponse = minioClient.listMultipart(bucket, null, obj, 1000, 0, uploadId, null, null);
		final List<Part> parts = listPartsResponse.result().partList();
		for (int i = 0; i < parts.size(); i++) {
			final Part part = parts.get(i);
			System.out.println(part.etag() + "--" +part.partNumber());
		}
//		minioClient.mergeMultipartUpload(bucket, null, bucketobj)
		this.mergeMultipartUpload(uploadId, bucket, obj);
		return AjaxResult.success(uploadId);
	}


	@ApiOperation("删除一个桶")
	@RequestMapping(value = "/deleteBucket", method = RequestMethod.GET)
	@ResponseBody
	public AjaxResult deleteBucket(@RequestParam String bucket) throws Exception {
		minioUtil.deleteBucket(bucket);
		return AjaxResult.success();
	}	
}